Preprocessing the Data Visualization Code

Loading in the Data

# all libraries
library(ggplot2)
library(dplyr)

Attaching package: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
library(tidyr)
library(viridis)
Loading required package: viridisLite
library(hrbrthemes)
library(gganimate)
library(plotly)

Attaching package: 'plotly'
The following object is masked from 'package:ggplot2':

    last_plot
The following object is masked from 'package:stats':

    filter
The following object is masked from 'package:graphics':

    layout
library(forcats)

# reading in the events dataset
events <- read.csv("../data/security_incidents.csv")
# ignoring the year 2025
events <- events %>%
  filter(Year != 2025)

# loading in my theme
source("../assets/my_theme.R")

Checking For Potential Issues

head(events)
  Incident.ID Year Month Day Country.Code    Country           Region District
1           1 1997     1  NA           KH   Cambodia Banteay Meanchey         
2           2 1997     1  NA           RW     Rwanda         Northern  Musanze
3           3 1997     2  NA           TJ Tajikistan                          
4           4 1997     2  NA           SO    Somalia       Lower Juba  Kismayo
5           5 1997     2  14           RW     Rwanda           Kigali   Kigali
6           7 1997     5  NA           CD   DR Congo                          
       City UN INGO ICRC NRCS.and.IFRC NNGO Other Nationals.killed
1            0    0    1             0    0     0                1
2 Ruhengeri  0    4    0             0    0     0                0
3            4    0    2             0    0     0                0
4   Kismayo  0    1    0             0    0     0                0
5    Kigali  1    0    0             0    0     0                1
6            0    0    0            10    0     0               10
  Nationals.wounded Nationals.kidnapped Total.nationals Internationals.killed
1                 0                   0               1                     0
2                 0                   0               0                     3
3                 0                   4               4                     0
4                 0                   0               0                     1
5                 0                   0               1                     0
6                 0                   0              10                     0
  Internationals.wounded Internationals.kidnapped Total.internationals
1                      0                        0                    0
2                      1                        0                    4
3                      0                        2                    2
4                      0                        0                    1
5                      0                        0                    0
6                      0                        0                    0
  Total.killed Total.wounded Total.kidnapped Total.affected Gender.Male
1            1             0               0              1           0
2            3             1               0              4           3
3            0             0               6              6           0
4            1             0               0              1           0
5            1             0               0              1           0
6           10             0               0             10           0
  Gender.Female Gender.Unknown Means.of.attack    Attack.context
1             0              1         Unknown           Unknown
2             1              0        Shooting              Raid
3             0              6      Kidnapping           Unknown
4             0              1         Unknown           Unknown
5             0              1        Shooting Individual attack
6             0             10         Unknown  Combat/Crossfire
         Location  Latitude Longitude     Motive
1         Unknown 14.070929 103.09992    Unknown
2 Office/compound -1.499840  29.63497    Unknown
3         Unknown 38.628173  70.81565           
4         Unknown -0.358216  42.54509  Political
5         Unknown -1.950851  30.06151  Political
6         Unknown -2.981434  23.82226 Incidental
                       Actor.type
1                         Unknown
2                         Unknown
3                         Unknown
4 Non-state armed group: Regional
5                         Unknown
6 Non-state armed group: National
                                                              Actor.name
1                                                                Unknown
2                                                                Unknown
3                                                                Unknown
4                                                 Al-Itihaad al-Islamiya
5                                                                Unknown
6 Alliance of Democratic Forces for the Liberation of Congo-Zaire (ADFL)
                                                                                                                                                                                                                     Details
1                                                                                                                                                   1 ICRC national staff killed while working in Banteay Meanchey province.
2                                                                      3 INGO international (Spanish) staff killed, 1 INGO international (US) staff gravely wounded during armed raid on INGO compound in Ruhengeri, Rwanda.
3 3 UN national staff, 1 UN international (Nigerian) staff, 1 ICRC international staff and 1 ICRC national staff kidnapped along with other (not included) UN staff, journalist and Tajik govt rep; released 48 hours later.
4                                                                                                                                                        1 INGO international staff killed by Al ittihad militia in Kismayo.
5                                                                                                                                                                      1 UN national staff shot and killed in Kigali Feb 14.
6                                                      10 NRCS staff first aid workers killed in fighting between Zairean troops and rebels from the Alliance of Democratic Forces for the Liberation of Congo-Zaire (ADFL).
  Verified   Source
1 Archived Archived
2 Archived Archived
3 Archived Archived
4 Archived Archived
5 Archived Archived
6 Archived Archived
summary(events)
  Incident.ID        Year          Month             Day       
 Min.   :   1   Min.   :1997   Min.   : 1.000   Min.   : 1.00  
 1st Qu.:1113   1st Qu.:2010   1st Qu.: 4.000   1st Qu.: 8.00  
 Median :2230   Median :2016   Median : 7.000   Median :15.00  
 Mean   :2231   Mean   :2015   Mean   : 6.592   Mean   :15.58  
 3rd Qu.:3352   3rd Qu.:2021   3rd Qu.:10.000   3rd Qu.:23.00  
 Max.   :4501   Max.   :2024   Max.   :12.000   Max.   :31.00  
                               NA's   :48       NA's   :377    
 Country.Code         Country             Region            District        
 Length:4290        Length:4290        Length:4290        Length:4290       
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
                                                                            
                                                                            
                                                                            
                                                                            
     City                 UN               INGO              ICRC        
 Length:4290        Min.   : 0.0000   Min.   : 0.0000   Min.   :0.00000  
 Class :character   1st Qu.: 0.0000   1st Qu.: 0.0000   1st Qu.:0.00000  
 Mode  :character   Median : 0.0000   Median : 0.0000   Median :0.00000  
                    Mean   : 0.4103   Mean   : 0.8142   Mean   :0.05162  
                    3rd Qu.: 0.0000   3rd Qu.: 1.0000   3rd Qu.:0.00000  
                    Max.   :92.0000   Max.   :49.0000   Max.   :8.00000  
                                                        NA's   :9        
 NRCS.and.IFRC         NNGO             Other         Nationals.killed 
 Min.   : 0.000   Min.   : 0.0000   Min.   :0.00000   Min.   : 0.0000  
 1st Qu.: 0.000   1st Qu.: 0.0000   1st Qu.:0.00000   1st Qu.: 0.0000  
 Median : 0.000   Median : 0.0000   Median :0.00000   Median : 0.0000  
 Mean   : 0.121   Mean   : 0.4723   Mean   :0.02448   Mean   : 0.6466  
 3rd Qu.: 0.000   3rd Qu.: 0.0000   3rd Qu.:0.00000   3rd Qu.: 1.0000  
 Max.   :19.000   Max.   :15.0000   Max.   :5.00000   Max.   :70.0000  
 NA's   :9        NA's   :9                                            
 Nationals.wounded Nationals.kidnapped Total.nationals  Internationals.killed
 Min.   : 0.0000   Min.   : 0.0000     Min.   : 0.000   Min.   : 0.00000     
 1st Qu.: 0.0000   1st Qu.: 0.0000     1st Qu.: 1.000   1st Qu.: 0.00000     
 Median : 0.0000   Median : 0.0000     Median : 1.000   Median : 0.00000     
 Mean   : 0.6289   Mean   : 0.4114     Mean   : 1.687   Mean   : 0.05618     
 3rd Qu.: 1.0000   3rd Qu.: 0.0000     3rd Qu.: 2.000   3rd Qu.: 0.00000     
 Max.   :37.0000   Max.   :19.0000     Max.   :92.000   Max.   :11.00000     
                                                                             
 Internationals.wounded Internationals.kidnapped Total.internationals
 Min.   : 0.00000       Min.   : 0.00000         Min.   : 0.0000     
 1st Qu.: 0.00000       1st Qu.: 0.00000         1st Qu.: 0.0000     
 Median : 0.00000       Median : 0.00000         Median : 0.0000     
 Mean   : 0.06457       Mean   : 0.08461         Mean   : 0.2054     
 3rd Qu.: 0.00000       3rd Qu.: 0.00000         3rd Qu.: 0.0000     
 Max.   :15.00000       Max.   :12.00000         Max.   :15.0000     
                                                                     
  Total.killed     Total.wounded     Total.kidnapped  Total.affected  
 Min.   : 0.0000   Min.   : 0.0000   Min.   : 0.000   Min.   : 0.000  
 1st Qu.: 0.0000   1st Qu.: 0.0000   1st Qu.: 0.000   1st Qu.: 1.000  
 Median : 0.0000   Median : 0.0000   Median : 0.000   Median : 1.000  
 Mean   : 0.7028   Mean   : 0.6935   Mean   : 0.496   Mean   : 1.892  
 3rd Qu.: 1.0000   3rd Qu.: 1.0000   3rd Qu.: 0.000   3rd Qu.: 2.000  
 Max.   :70.0000   Max.   :37.0000   Max.   :20.000   Max.   :92.000  
                                                                      
  Gender.Male      Gender.Female    Gender.Unknown    Means.of.attack   
 Min.   : 0.0000   Min.   :0.0000   Min.   : 0.0000   Length:4290       
 1st Qu.: 0.0000   1st Qu.:0.0000   1st Qu.: 0.0000   Class :character  
 Median : 1.0000   Median :0.0000   Median : 0.0000   Mode  :character  
 Mean   : 0.8963   Mean   :0.1394   Mean   : 0.8564                     
 3rd Qu.: 1.0000   3rd Qu.:0.0000   3rd Qu.: 1.0000                     
 Max.   :17.0000   Max.   :7.0000   Max.   :92.0000                     
                                                                        
 Attack.context       Location            Latitude         Longitude      
 Length:4290        Length:4290        Min.   :-34.884   Min.   :-102.28  
 Class :character   Class :character   1st Qu.:  5.836   1st Qu.:  28.75  
 Mode  :character   Mode  :character   Median : 13.426   Median :  34.47  
                                       Mean   : 16.732   Mean   :  36.53  
                                       3rd Qu.: 33.096   3rd Qu.:  45.40  
                                       Max.   : 52.253   Max.   : 179.01  
                                       NA's   :13        NA's   :13       
    Motive           Actor.type         Actor.name          Details         
 Length:4290        Length:4290        Length:4290        Length:4290       
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
                                                                            
                                                                            
                                                                            
                                                                            
   Verified            Source         
 Length:4290        Length:4290       
 Class :character   Class :character  
 Mode  :character   Mode  :character  
                                      
                                      
                                      
                                      
cat("----------------------\n")
----------------------
cat("COLUMNS:\n")
COLUMNS:
cat("----------------------\n")
----------------------
print(colnames(events))
 [1] "Incident.ID"              "Year"                    
 [3] "Month"                    "Day"                     
 [5] "Country.Code"             "Country"                 
 [7] "Region"                   "District"                
 [9] "City"                     "UN"                      
[11] "INGO"                     "ICRC"                    
[13] "NRCS.and.IFRC"            "NNGO"                    
[15] "Other"                    "Nationals.killed"        
[17] "Nationals.wounded"        "Nationals.kidnapped"     
[19] "Total.nationals"          "Internationals.killed"   
[21] "Internationals.wounded"   "Internationals.kidnapped"
[23] "Total.internationals"     "Total.killed"            
[25] "Total.wounded"            "Total.kidnapped"         
[27] "Total.affected"           "Gender.Male"             
[29] "Gender.Female"            "Gender.Unknown"          
[31] "Means.of.attack"          "Attack.context"          
[33] "Location"                 "Latitude"                
[35] "Longitude"                "Motive"                  
[37] "Actor.type"               "Actor.name"              
[39] "Details"                  "Verified"                
[41] "Source"                  
print(names(events))
 [1] "Incident.ID"              "Year"                    
 [3] "Month"                    "Day"                     
 [5] "Country.Code"             "Country"                 
 [7] "Region"                   "District"                
 [9] "City"                     "UN"                      
[11] "INGO"                     "ICRC"                    
[13] "NRCS.and.IFRC"            "NNGO"                    
[15] "Other"                    "Nationals.killed"        
[17] "Nationals.wounded"        "Nationals.kidnapped"     
[19] "Total.nationals"          "Internationals.killed"   
[21] "Internationals.wounded"   "Internationals.kidnapped"
[23] "Total.internationals"     "Total.killed"            
[25] "Total.wounded"            "Total.kidnapped"         
[27] "Total.affected"           "Gender.Male"             
[29] "Gender.Female"            "Gender.Unknown"          
[31] "Means.of.attack"          "Attack.context"          
[33] "Location"                 "Latitude"                
[35] "Longitude"                "Motive"                  
[37] "Actor.type"               "Actor.name"              
[39] "Details"                  "Verified"                
[41] "Source"                  
cat("----------------------\n")
----------------------
cat("GENERAL INFORMATION:\n")
GENERAL INFORMATION:
cat("----------------------\n")
----------------------
str(events)
'data.frame':   4290 obs. of  41 variables:
 $ Incident.ID             : int  1 2 3 4 5 7 6 11 12 8 ...
 $ Year                    : int  1997 1997 1997 1997 1997 1997 1997 1997 1997 1997 ...
 $ Month                   : int  1 1 2 2 2 5 5 6 6 6 ...
 $ Day                     : int  NA NA NA NA 14 NA 7 NA 8 14 ...
 $ Country.Code            : chr  "KH" "RW" "TJ" "SO" ...
 $ Country                 : chr  "Cambodia" "Rwanda" "Tajikistan" "Somalia" ...
 $ Region                  : chr  "Banteay Meanchey" "Northern" "" "Lower Juba" ...
 $ District                : chr  "" "Musanze" "" "Kismayo" ...
 $ City                    : chr  "" "Ruhengeri" "" "Kismayo" ...
 $ UN                      : int  0 0 4 0 1 0 3 1 0 1 ...
 $ INGO                    : int  0 4 0 1 0 0 0 0 1 0 ...
 $ ICRC                    : int  1 0 2 0 0 0 0 0 0 0 ...
 $ NRCS.and.IFRC           : int  0 0 0 0 0 10 0 0 0 0 ...
 $ NNGO                    : int  0 0 0 0 0 0 0 0 0 0 ...
 $ Other                   : int  0 0 0 0 0 0 0 0 0 0 ...
 $ Nationals.killed        : int  1 0 0 0 1 10 1 1 1 1 ...
 $ Nationals.wounded       : int  0 0 0 0 0 0 2 0 0 0 ...
 $ Nationals.kidnapped     : int  0 0 4 0 0 0 0 0 0 0 ...
 $ Total.nationals         : int  1 0 4 0 1 10 3 1 1 1 ...
 $ Internationals.killed   : int  0 3 0 1 0 0 0 0 0 0 ...
 $ Internationals.wounded  : int  0 1 0 0 0 0 0 0 0 0 ...
 $ Internationals.kidnapped: int  0 0 2 0 0 0 0 0 0 0 ...
 $ Total.internationals    : int  0 4 2 1 0 0 0 0 0 0 ...
 $ Total.killed            : int  1 3 0 1 1 10 1 1 1 1 ...
 $ Total.wounded           : int  0 1 0 0 0 0 2 0 0 0 ...
 $ Total.kidnapped         : int  0 0 6 0 0 0 0 0 0 0 ...
 $ Total.affected          : int  1 4 6 1 1 10 3 1 1 1 ...
 $ Gender.Male             : int  0 3 0 0 0 0 1 1 1 1 ...
 $ Gender.Female           : int  0 1 0 0 0 0 0 0 0 0 ...
 $ Gender.Unknown          : int  1 0 6 1 1 10 2 0 0 0 ...
 $ Means.of.attack         : chr  "Unknown" "Shooting" "Kidnapping" "Unknown" ...
 $ Attack.context          : chr  "Unknown" "Raid" "Unknown" "Unknown" ...
 $ Location                : chr  "Unknown" "Office/compound" "Unknown" "Unknown" ...
 $ Latitude                : num  14.071 -1.5 38.628 -0.358 -1.951 ...
 $ Longitude               : num  103.1 29.6 70.8 42.5 30.1 ...
 $ Motive                  : chr  "Unknown" "Unknown" "" "Political" ...
 $ Actor.type              : chr  "Unknown" "Unknown" "Unknown" "Non-state armed group: Regional" ...
 $ Actor.name              : chr  "Unknown" "Unknown" "Unknown" "Al-Itihaad al-Islamiya" ...
 $ Details                 : chr  "1 ICRC national staff killed while working in Banteay Meanchey province." "3 INGO international (Spanish) staff killed, 1 INGO international (US) staff gravely wounded during armed raid "| __truncated__ "3 UN national staff, 1 UN international (Nigerian) staff, 1 ICRC international staff and 1 ICRC national staff "| __truncated__ "1 INGO international staff killed by Al ittihad militia in Kismayo." ...
 $ Verified                : chr  "Archived" "Archived" "Archived" "Archived" ...
 $ Source                  : chr  "Archived" "Archived" "Archived" "Archived" ...
cat("----------------------\n")
----------------------
cat("BASIC STATISTICS:\n")
BASIC STATISTICS:
cat("----------------------\n")
----------------------
summary(events)
  Incident.ID        Year          Month             Day       
 Min.   :   1   Min.   :1997   Min.   : 1.000   Min.   : 1.00  
 1st Qu.:1113   1st Qu.:2010   1st Qu.: 4.000   1st Qu.: 8.00  
 Median :2230   Median :2016   Median : 7.000   Median :15.00  
 Mean   :2231   Mean   :2015   Mean   : 6.592   Mean   :15.58  
 3rd Qu.:3352   3rd Qu.:2021   3rd Qu.:10.000   3rd Qu.:23.00  
 Max.   :4501   Max.   :2024   Max.   :12.000   Max.   :31.00  
                               NA's   :48       NA's   :377    
 Country.Code         Country             Region            District        
 Length:4290        Length:4290        Length:4290        Length:4290       
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
                                                                            
                                                                            
                                                                            
                                                                            
     City                 UN               INGO              ICRC        
 Length:4290        Min.   : 0.0000   Min.   : 0.0000   Min.   :0.00000  
 Class :character   1st Qu.: 0.0000   1st Qu.: 0.0000   1st Qu.:0.00000  
 Mode  :character   Median : 0.0000   Median : 0.0000   Median :0.00000  
                    Mean   : 0.4103   Mean   : 0.8142   Mean   :0.05162  
                    3rd Qu.: 0.0000   3rd Qu.: 1.0000   3rd Qu.:0.00000  
                    Max.   :92.0000   Max.   :49.0000   Max.   :8.00000  
                                                        NA's   :9        
 NRCS.and.IFRC         NNGO             Other         Nationals.killed 
 Min.   : 0.000   Min.   : 0.0000   Min.   :0.00000   Min.   : 0.0000  
 1st Qu.: 0.000   1st Qu.: 0.0000   1st Qu.:0.00000   1st Qu.: 0.0000  
 Median : 0.000   Median : 0.0000   Median :0.00000   Median : 0.0000  
 Mean   : 0.121   Mean   : 0.4723   Mean   :0.02448   Mean   : 0.6466  
 3rd Qu.: 0.000   3rd Qu.: 0.0000   3rd Qu.:0.00000   3rd Qu.: 1.0000  
 Max.   :19.000   Max.   :15.0000   Max.   :5.00000   Max.   :70.0000  
 NA's   :9        NA's   :9                                            
 Nationals.wounded Nationals.kidnapped Total.nationals  Internationals.killed
 Min.   : 0.0000   Min.   : 0.0000     Min.   : 0.000   Min.   : 0.00000     
 1st Qu.: 0.0000   1st Qu.: 0.0000     1st Qu.: 1.000   1st Qu.: 0.00000     
 Median : 0.0000   Median : 0.0000     Median : 1.000   Median : 0.00000     
 Mean   : 0.6289   Mean   : 0.4114     Mean   : 1.687   Mean   : 0.05618     
 3rd Qu.: 1.0000   3rd Qu.: 0.0000     3rd Qu.: 2.000   3rd Qu.: 0.00000     
 Max.   :37.0000   Max.   :19.0000     Max.   :92.000   Max.   :11.00000     
                                                                             
 Internationals.wounded Internationals.kidnapped Total.internationals
 Min.   : 0.00000       Min.   : 0.00000         Min.   : 0.0000     
 1st Qu.: 0.00000       1st Qu.: 0.00000         1st Qu.: 0.0000     
 Median : 0.00000       Median : 0.00000         Median : 0.0000     
 Mean   : 0.06457       Mean   : 0.08461         Mean   : 0.2054     
 3rd Qu.: 0.00000       3rd Qu.: 0.00000         3rd Qu.: 0.0000     
 Max.   :15.00000       Max.   :12.00000         Max.   :15.0000     
                                                                     
  Total.killed     Total.wounded     Total.kidnapped  Total.affected  
 Min.   : 0.0000   Min.   : 0.0000   Min.   : 0.000   Min.   : 0.000  
 1st Qu.: 0.0000   1st Qu.: 0.0000   1st Qu.: 0.000   1st Qu.: 1.000  
 Median : 0.0000   Median : 0.0000   Median : 0.000   Median : 1.000  
 Mean   : 0.7028   Mean   : 0.6935   Mean   : 0.496   Mean   : 1.892  
 3rd Qu.: 1.0000   3rd Qu.: 1.0000   3rd Qu.: 0.000   3rd Qu.: 2.000  
 Max.   :70.0000   Max.   :37.0000   Max.   :20.000   Max.   :92.000  
                                                                      
  Gender.Male      Gender.Female    Gender.Unknown    Means.of.attack   
 Min.   : 0.0000   Min.   :0.0000   Min.   : 0.0000   Length:4290       
 1st Qu.: 0.0000   1st Qu.:0.0000   1st Qu.: 0.0000   Class :character  
 Median : 1.0000   Median :0.0000   Median : 0.0000   Mode  :character  
 Mean   : 0.8963   Mean   :0.1394   Mean   : 0.8564                     
 3rd Qu.: 1.0000   3rd Qu.:0.0000   3rd Qu.: 1.0000                     
 Max.   :17.0000   Max.   :7.0000   Max.   :92.0000                     
                                                                        
 Attack.context       Location            Latitude         Longitude      
 Length:4290        Length:4290        Min.   :-34.884   Min.   :-102.28  
 Class :character   Class :character   1st Qu.:  5.836   1st Qu.:  28.75  
 Mode  :character   Mode  :character   Median : 13.426   Median :  34.47  
                                       Mean   : 16.732   Mean   :  36.53  
                                       3rd Qu.: 33.096   3rd Qu.:  45.40  
                                       Max.   : 52.253   Max.   : 179.01  
                                       NA's   :13        NA's   :13       
    Motive           Actor.type         Actor.name          Details         
 Length:4290        Length:4290        Length:4290        Length:4290       
 Class :character   Class :character   Class :character   Class :character  
 Mode  :character   Mode  :character   Mode  :character   Mode  :character  
                                                                            
                                                                            
                                                                            
                                                                            
   Verified            Source         
 Length:4290        Length:4290       
 Class :character   Class :character  
 Mode  :character   Mode  :character  
                                      
                                      
                                      
                                      
# rows and columns
Nr0 <- nrow(events)
Nc0 <- ncol(events)
cat("Nrows = ", Nr0, "\nNcol = ", Nc0, "\nMatrix entries = ", Nr0 * Nc0, "\n")
Nrows =  4290 
Ncol =  41 
Matrix entries =  175890 

Understanding the Motive Variable

colnames(events)
 [1] "Incident.ID"              "Year"                    
 [3] "Month"                    "Day"                     
 [5] "Country.Code"             "Country"                 
 [7] "Region"                   "District"                
 [9] "City"                     "UN"                      
[11] "INGO"                     "ICRC"                    
[13] "NRCS.and.IFRC"            "NNGO"                    
[15] "Other"                    "Nationals.killed"        
[17] "Nationals.wounded"        "Nationals.kidnapped"     
[19] "Total.nationals"          "Internationals.killed"   
[21] "Internationals.wounded"   "Internationals.kidnapped"
[23] "Total.internationals"     "Total.killed"            
[25] "Total.wounded"            "Total.kidnapped"         
[27] "Total.affected"           "Gender.Male"             
[29] "Gender.Female"            "Gender.Unknown"          
[31] "Means.of.attack"          "Attack.context"          
[33] "Location"                 "Latitude"                
[35] "Longitude"                "Motive"                  
[37] "Actor.type"               "Actor.name"              
[39] "Details"                  "Verified"                
[41] "Source"                  
unique(events$Motive)
[1] "Unknown"    ""           "Political"  "Incidental" "Economic"  
[6] "Disputed"   "Other"     
table(events$Motive)

             Disputed   Economic Incidental      Other  Political    Unknown 
         4        116        647        764         22        810       1927 
nrow(events)
[1] 4290
# Unknown, Other, Disputed, Political, Incidental, Economic

Creating the Visualizations

Histogram of Number of Events by Motive

ggplot(events %>% filter(!is.na(Motive) & Motive != ""), aes(x = Motive)) + # ignore NA/empty
  geom_bar(fill = "#0D0887", color = "#0D0887") + # custom color
  theme_minimal() +
  labs(
    title = "Number of Incidents by Motive Type",
    x = "Motive",
    y = "Count"
  ) + my_theme

Animated Time Series

# dropping 'OTHER' AND 'DISPUTED':
events <- events %>%
  filter(!Motive %in% c("Other", "Disputed", "Unknown"))

# group by the year and the motive type
events_summary <- events %>%
    filter(!is.na(Motive) & Motive != "") %>%
    group_by(Year, Motive) %>%
    summarise(n = n(), .groups = 'drop')

# creating a time series plot with each line being a motive type
time <- ggplot(events_summary, aes(x = Year, y = n, group = Motive, color = Motive)) +
    geom_line() +
    geom_point() +
    scale_color_viridis(discrete = TRUE) +
    ggtitle("Motives of Incidences over the Years") +
    theme_ipsum() +
    ylab("Number of Motive Types") +
    transition_reveal(Year)

# animating and saving
animate(time)
`geom_line()`: Each group consists of only one observation.
ℹ Do you need to adjust the group aesthetic?
`geom_line()`: Each group consists of only one observation.
ℹ Do you need to adjust the group aesthetic?

anim_save("motives_animation.gif", animation = animate(time))
`geom_line()`: Each group consists of only one observation.
ℹ Do you need to adjust the group aesthetic?
`geom_line()`: Each group consists of only one observation.
ℹ Do you need to adjust the group aesthetic?

Static Time Series

# aggregating by motive type
events_summary <- events %>%
    filter(!is.na(Motive) & Motive != "") %>%
    group_by(Year, Motive) %>%
    summarise(n = n(), .groups = 'drop')

# taking only three motives
filtered_summary <- events_summary %>%
  filter(Motive %in% c("Economic", "Political", "Incidental"))

# Static time series plot
ggplot(filtered_summary, aes(x = Year, y = n, color = Motive)) +
  geom_line() +
  geom_point() +
  scale_color_manual(values = c(
        "Political" = "#F0F921",
        "Economic" = "#F89441",
        "Incidental" = "#933b94"
  )) +
  ggtitle("") +
  ylab("") +
  xlab("") +
  my_theme +
  theme(legend.position = "none")

Political Choropleth

# subsetting by just the political motive and by country
political_events <- events %>%
  filter(Motive == "Political") %>%
  group_by(Country) %>%
  summarise(count = n())

# choropleth of political events across the country
plot_geo(political_events) %>% # making it interactive
  add_trace(
    locations = ~Country,
    locationmode = 'country names',
    z = ~count,
    colorscale = list( # custom color scale
      c(0, "#0D0887"), 
      c(0.33, "#933b94"),
      c(0.66, "#F89441"),
      c(1, "#F0F921")
    ),
    text = ~paste(Country, "<br>Count:", count),
    hoverinfo = "text"
  ) %>%
  colorbar(title = list(text = "Count", font = list(family = "Didot"))) %>%
  layout(
    title = list(
      text = "Count of Politically Motivated Incidents by Country",
      font = list(family = "Didot")
    ),
    font = list(family = "Didot"),
    geo = list(showframe = FALSE)
  )

Economic Choropleth

# subsetting by just the economic motive and by country
economic_events <- events %>%
  filter(Motive == "Economic") %>%
  group_by(Country) %>%
  summarise(count = n())

# choropleth of economic events across the country
plot_geo(economic_events) %>% # making it interactive
  add_trace(
    locations = ~Country,
    locationmode = 'country names',
    z = ~count,
    colorscale = list( # custom color scale
      c(0, "#0D0887"), 
      c(0.33, "#933b94"),
      c(0.66, "#F89441"),
      c(1, "#F0F921")
    ),
    text = ~paste(Country, "<br>Count:", count),
    hoverinfo = "text"
  ) %>%
  colorbar(title = list(text = "Count", font = list(family = "Didot"))) %>%
  layout(
    title = list(
      text = "Count of Economically Motivated Incidents by Country",
      font = list(family = "Didot")
    ),
    font = list(family = "Didot"),
    geo = list(showframe = FALSE)
  )

Incidental Choropleth

# subsetting by just the incidental motive and by country
inc_events <- events %>%
  filter(Motive == "Incidental") %>%
  group_by(Country) %>%
  summarise(count = n())

# choropleth of incidental events across the country
plot_geo(inc_events) %>% # making it interactive
  add_trace(
    locations = ~Country,
    locationmode = 'country names',
    z = ~count,
    colorscale = list( # custom color scale
      c(0, "#0D0887"), 
      c(0.33, "#933b94"),
      c(0.66, "#F89441"),
      c(1, "#F0F921")
    ),
    text = ~paste(Country, "<br>Count:", count),
    hoverinfo = "text"
  ) %>%
  colorbar(title = list(text = "Count", font = list(family = "Didot"))) %>%
  layout(
    title = list(
      text = "Count of Incidentally Motivated Incidents by Country",
      font = list(family = "Didot")
    ),
    font = list(family = "Didot"),
    geo = list(showframe = FALSE)
  )

Dropping ‘Unknown’

# DROPPING THE 'UNKNOWN' FOR THE REST
events <- events %>%
  filter(!Motive %in% c("Unknown"))

Stacked Bar Plot

# aggregating the harm types by the motive type
harm_summary <- events %>%
  filter(!is.na(Motive) & Motive != "" & !Motive %in% c("Disputed", "Other")) %>%
  group_by(Motive) %>%
  summarise(Total_Killed = sum(`Total.killed`, na.rm = TRUE),
            Total_Wounded = sum(`Total.wounded`, na.rm = TRUE),
            Total_Kidnapped = sum(`Total.kidnapped`, na.rm = TRUE)) %>%
  pivot_longer(cols = starts_with("Total"), names_to = "Metric", values_to = "Count") # reshaping to long format

# ordering motive types by total count (highest count = first)
harm_summary <- harm_summary %>%
  mutate(Motive_Type = fct_reorder(Motive, -Count))

# stacked bar plot
p <- ggplot(harm_summary, aes(x = Motive_Type, y = Count, fill = Metric)) +
  geom_bar(stat = "identity") +
  coord_flip() + # making it horizontal
  scale_fill_manual(values = c( # custom colors
        "Total_Killed" = "#F89441",
        "Total_Wounded" = "#933b94",
        "Total_Kidnapped" = "#0D0887"
    )) +
  labs(title = "Total Wounded, Kidnapped, and Affected by Motive Type",
       x = "Motive", y = NULL, fill = "Metric") +
  my_theme

ggplotly(p) # making it interactive

Pie Chart by Agency

# sums events by the agency and the motive
agency_props <- events %>%
  filter(!is.na(Motive) & Motive != "") %>% # drop NA/missing
  pivot_longer(cols = c("UN", "INGO", "ICRC", "NRCS.and.IFRC", "NNGO", "Other"),
               names_to = "Agency", values_to = "IncidentCount") %>% # long format
  filter(!is.na(IncidentCount) & IncidentCount > 0) %>%  # Only include non-zero incidents
  group_by(Agency, Motive) %>%
  summarise(Count = sum(IncidentCount, na.rm = TRUE), .groups = "drop") %>%
  group_by(Agency) %>%
  mutate(Percent = Count / sum(Count)) %>% # calculate percent share
  ungroup()

# creating pie charts for motives across agencies
ggplot(agency_props, aes(x = 1, y = Percent, fill = Motive)) +
  geom_col(width = 0.6, color = "white") +
  coord_polar(theta = "y") +
  facet_wrap(~ Agency) + # facet by the agency type
  scale_fill_manual(values = c( # custom colors
        "Political" = "#F0F921",
        "Economic" = "#F89441",
        "Incidental" = "#933b94"
  )) +
  theme_void(base_family = "Didot", base_size = 14) + 
  theme( # manually appplying theme due to pie chart issues
    axis.text = element_blank(),
    axis.ticks = element_blank(),
    axis.title = element_blank(),
    panel.grid = element_blank(),
    panel.background = element_blank(),
    strip.text = element_text(family = "Didot", size = 14),
    strip.background = element_blank(),
    plot.title = element_text(family = "Didot", size = 16, face = "bold"),
    legend.title = element_text(family = "Didot"),
    legend.text = element_text(family = "Didot", size = 12)
  ) + 
  labs(title = "Distribution of Incidence Motive Type per Agency",
       fill = "Motive")

Reverse Pie Chart

# Pivot agency columns long
agency_props <- events %>%
  filter(!is.na(Motive) & Motive != "") %>%
  pivot_longer(cols = c("UN", "INGO", "ICRC", "NRCS.and.IFRC", "NNGO", "Other"),
               names_to = "Agency", values_to = "IncidentCount") %>%
  filter(!is.na(IncidentCount) & IncidentCount > 0) %>%  # Only include non-zero incidents
  group_by(Agency, Motive) %>%
  summarise(Count = sum(IncidentCount, na.rm = TRUE), .groups = "drop") %>%
  group_by(Agency) %>%
  mutate(Percent = Count / sum(Count)) %>%
  ungroup()

ggplot(agency_props, aes(x = 1, y = Percent, fill = Motive)) +
  geom_col(width = 0.6, color = "white") +
  coord_polar(theta = "y") +
  facet_wrap(~ Agency) +
  scale_fill_viridis_d(option = "plasma") +
  theme_void() +
  labs(title = "Distribution of Motives per Agency",
       fill = "Motive")

Grouped Bar Chart (Nats versus Inters)

# sums the number of events by national/international
nationality_long <- events %>%
  filter(!is.na(Motive) & Motive != "") %>% # ignore missing
  pivot_longer(cols = c(Total.nationals, Total.internationals),
               names_to = "Group", values_to = "Count") %>% # pivot long
  mutate(Group = ifelse(Group == "Total.nationals", "Nationals", "Internationals"))

# aggregate totals by motive and group
nationality_summary <- nationality_long %>%
  group_by(Motive, Group) %>%
  summarise(Total = sum(Count, na.rm = TRUE), .groups = "drop")

# plotting grouped bar chart
g <- ggplot(nationality_summary, aes(x = reorder(Motive, -Total), y = Total, fill = Group)) +
  geom_bar(stat = "identity", position = "dodge") +  # dodged bars
  scale_fill_manual(values = c(
        "Internationals" = "#933b94", # custom colors
        "Nationals" = "#0D0887"
    )) +
  labs(title = "Total Nationals and International Impacted by Motive Type",
       subtitle = "Nationals vs Internationals (Grouped Bars)",
       x = "", y = "Total", fill = "Group") +
  my_theme +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

ggplotly(g) # making it interactive

Heatmap

# aggregating wounding type by motive type and splitting btwn nats/internationals
harm_long <- events %>%
  filter(!is.na(Motive) & Motive != "") %>% # ignore missing
  pivot_longer( # pivoting all to long format
    cols = c(
      Nationals.killed, Nationals.wounded, Nationals.kidnapped,
      Internationals.killed, Internationals.wounded, Internationals.kidnapped
    ), # renames
    names_to = c("Group", "HarmType"),
    names_sep = "\\.",
    values_to = "Count"
  ) %>%
  mutate(
    Group = ifelse(Group == "Nationals", "Nationals", "Internationals"),
    HarmType = stringr::str_to_title(HarmType)
  )

# aggregating for the heatmap
heatmap_data <- harm_long %>% # sums # of harmed for each motive, group, harm type
  group_by(Group, Motive, HarmType) %>%
  summarise(Total = sum(Count, na.rm = TRUE), .groups = "drop")

# creating the heatmap
g <- ggplot(heatmap_data, aes(x = HarmType, y = Motive, fill = Total)) +
  geom_tile(color = "white") +
  facet_wrap(~ Group) + # facet by national/international
  scale_fill_viridis_c(option = "plasma") +
  labs(
    title = "Type of Harm by Motive for Nationals and Internationals",
    subtitle = "Separated by Group (Nationals vs Internationals)",
    x = NULL, y = NULL, fill = "Total"
  ) +
  my_theme + # adding my theme
  theme(
    axis.text.x = element_text(angle = 30, hjust = 1),
    strip.text = element_text(size = 12, face = "bold"),
    strip.background = element_blank(),
  ) 

ggplotly(g) # making it interactive